<?php
/**
 * | ---------------------------------------------------------------------------------------------------
 * | Author：johnxu <fsyzxz@163.com>.
 * | ---------------------------------------------------------------------------------------------------
 * | Home: https://www.johnxu.net.
 * | ---------------------------------------------------------------------------------------------------
 * | Data: 2018/12/30
 * | ---------------------------------------------------------------------------------------------------
 * | Desc: 优化的websocket基础类库
 * | ---------------------------------------------------------------------------------------------------
 */

class WebSocket
{
    const HOST = '0.0.0.0';
    const PORT = 9501;

    /**
     * @var swoole_websocket_server
     */
    private $ws;

    public function __construct()
    {
        $this->ws = new swoole_websocket_server( self::HOST, self::PORT );

        $this->set();

        $this->ws->on( 'open', array( $this, 'onOpen' ) );
        $this->ws->on( 'message', array( $this, 'onMessage' ) );
        // 添加任务
        $this->ws->on( 'task', array( $this, 'onTask' ) );
        $this->ws->on( 'finish', array( $this, 'onFinish' ) );
        $this->ws->on( 'close', array( $this, 'onClose' ) );
        $this->ws->on( 'request', array( $this, 'onRequest' ) );

        $this->ws->start();
    }

    /**
     * 打开时候处理
     *
     * @param swoole_websocket_server $server
     * @param swoole_http_request     $request
     */
    public function onOpen( swoole_websocket_server $server, swoole_http_request $request )
    {
        var_dump( $request->fd . '打开了连接' );
    }

    /**
     * 接收消息处理
     *
     * @param swoole_websocket_server $server
     * @param swoole_websocket_frame  $frame
     */
    public function onMessage( swoole_websocket_server $server, swoole_websocket_frame $frame )
    {
        $server->push( $frame->fd, "你发送的信息是：{$frame->data}" );
        // 投递任务
        $data = array(
            'task' => 1,
            'fd'   => $frame->fd
        );
        $server->task( $data );
    }

    /**
     * 客户端断开连接
     *
     * @param swoole_websocket_server $server
     * @param                         $fd
     */
    public function onClose( swoole_websocket_server $server, $fd )
    {
        var_dump( "{$fd} 断开连接" );
    }

    /**
     * 处理http请求
     *
     * @param swoole_http_request  $request
     * @param swoole_http_response $response
     */
    public function onRequest( swoole_http_request $request, swoole_http_response $response )
    {
        $response->end( 'Welcome to websocket http.' );
    }

    /**
     * 任务处理
     *
     * @param swoole_server $server
     * @param int           $task_id       任务号，从0开始
     * @param int           $src_worker_id 进程号
     * @param               $data          数据
     *
     * @return string
     */
    public function onTask( swoole_server $server, int $task_id, int $src_worker_id, $data )
    {
        var_dump( "任务创：{$task_id}，进程号：{$src_worker_id}，数据：" );
        print_r( $data );
        sleep( 10 );

        return "task finished.";
    }

    /**
     * 任务执行完成触发
     *
     * @param swoole_server $serv
     * @param int           $task_id 任务号
     * @param string        $data    onTask return的数据
     */
    public function onFinish( swoole_server $serv, int $task_id, string $data )
    {
        var_dump( "任务：{$task_id}" );
        echo "finished: ";
        print_r( $data );
    }

    /**
     * 基础配置
     */
    public function set()
    {
        $this->ws->set( array(
            'log_level'             => 5,
            'enable_static_handler' => true,
            'document_root'         => '/home/wwwroot/johnxu.swoole.local.cn/data',
            'task_worker_num'       => 10, // 任务数量
            'worker_num'            => 2
        ) );
    }
}

new WebSocket();
